package package1;

import java.io.BufferedReader;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
import org.apache.commons.codec.binary.Base64;
//import sun.misc.BASE64Decoder;
//import sun.misc.BASE64Encoder;

/**
 * extractText method details for encoder and decoder, encryption and decryption
 * applicable to post request for encryption and decryption
 * 
 * @author Alvin
 */
public class TestForCharacterDealing {

	@SuppressWarnings("unused")
	public static void main(String[] args) throws Exception {
		readChineseCharcter();
		// encodingAndDecodingTest();
		// gbkAndUtf_8();
		// dealWithCharSetEncodingAndDecoding();
		// convertMessyCode();
		// extractTextTest();
		String a = convertCharset("中国", getSystemEncodingCharset(), "gbk");

	}

	private static void readChineseCharcter() throws IOException {
		File f= new File("C:\\Users\\Administrator\\Desktop\\222.txt");
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "gbk"));
		String temp;
		while((temp=br.readLine())!=null){
			System.err.println(temp);
		}
	}

	private static String getSystemEncodingCharset() {
		return System.getProperty("file.encoding");
	}

	private static String convertCharset(String str, String from, String to) throws IOException {
		return new String(str.getBytes(from), to);
	}

	@SuppressWarnings("unused")
	private static void extractTextTest() throws Exception {
		String res = "";
		String a = "package package1;";
		res = extractText(a, "package ", ";");
		System.err.println(res);
		res = extractText("11abc22", "11", "22");
		System.exit(0);
	}

	/**
	 * the method needs more robust detection
	 * 
	 * @param str
	 * @param t1
	 * @param t2
	 * @return
	 * @throws Exception
	 */

	@SuppressWarnings("unused")
	public static String extractText(String str, String t1, String t2) throws Exception {
		if (!str.contains(t1))
			exception(str + "doesn't contain " + t1);
		if (!str.contains(t2))
			exception(str + "doesn't contain " + t2);
		// like checking after t1 was found, if t2 could be found

		int t1Index = str.indexOf(t1);
		int t1Len = t1.length();
		String rest = str.substring(t1Index + t1Len, str.length());
		if (!rest.contains(t2))
			exception(str + "doesn't contain " + t2 + " after " + t1 + " has been found!");
		System.err.println(rest);
		int t2Index = str.indexOf(t2);
		int t2Len = t2.length();
		return str.substring(t1Index + t1Len, t2Index);
	}

	private static void exception(String string) throws Exception {
		boolean print = true;
		if (print)
			System.err.println(string);
		else
			throw new Exception(string);
	}

	@SuppressWarnings({ "unused", "resource" })
	private static void dealWithCharSetEncodingAndDecoding() throws Exception {
		Scanner scan = new Scanner(System.in);
		String cmd;
		Integer cmdNum = 0;
		boolean systemRun = true;
		File f = new File("C:\\Users\\alvin.wang\\Desktop\\123.txt");
		while (systemRun) {
			System.err.println("1. createFileWithMessyChar 2. convertMessyFile  3. convertMessyCode");
			cmd = scan.nextLine();
			cmdNum = Integer.parseInt(cmd);
			if (cmd.equalsIgnoreCase("exit")) {
				systemRun = false;
				continue;
			}
			switch (cmdNum) {
			case 1:
				System.err.println(
						"input your file address, or input 'default' to use default address of C:\\Users\\alvin.wang\\Desktop\\123.txt");
				cmd = scan.nextLine();
				if (!cmd.trim().equalsIgnoreCase("default"))
					f = new File(cmd);
				createFileWithMessyChar(f);
				break;
			case 2:
				System.err.print("input decode charset:");
				String charsetFrom = scan.nextLine();
				System.err.print("input encode charset:");
				String charsetTo = scan.nextLine();
				convertMessyFile(f, charsetFrom, charsetTo);
				break;
			case 3:
				convertMessyCode();
				break;
			default:
				System.err.println("input invalid");
				break;
			}
		}
		System.err.println("thanks for using the system");
		System.exit(0);
	}

	/**
	 * 
	 * @param f
	 *            file name that needs convert the messy chars
	 * @param charsetFrom
	 *            char set to decode the messy chars
	 * @param charsetTo
	 *            char set to encode the byte array of messy chars into
	 * @throws IOException
	 */
	private static void convertMessyFile(File f, String charsetFrom, String charsetTo) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(f));
		String buf;
		String ch;
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		while ((buf = br.readLine()) != null) {
			sb1.append(buf);
			ch = new String(buf.getBytes(charsetFrom), charsetTo);
			sb2.append(ch);
		}
		System.err.println("File content with messy code:" + sb1.toString());
		br.close();
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		System.err.println("File content after convert:" + sb2.toString() + "\r\n@" + f.getAbsolutePath());
		bw.write(sb2.toString());
		bw.close();
	}

	private static void createFileWithMessyChar(File f) throws IOException {
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		String a = "你好我是中国�?..";
		String b = new String(a.getBytes("utf-8"), "gbk");
		System.err.println("input:" + b + "\r\n@" + f.getAbsolutePath());
		bw.write(b);
		bw.close();
	}

	/**
	 * input the messy chars output the 16 possible results of the decoding
	 * 
	 * @throws IOException
	 * @throws Exception
	 */
	@SuppressWarnings("resource")
	private static void convertMessyCode() throws IOException, Exception {
		System.err.print("system initializing");
		for (int i = 0; i < 3; i++) {
			Thread.sleep(300);
			System.err.print(".");
		}
		System.err.println();
		String GBK = "gbk";
		String UTF_8 = "utf-8";
		String UTF_16 = "utf-16";
		String UTF_32 = "utf-32";
		String ISO = "ISO-8859-1";
		String GB = "GB2312";

		ArrayList<String> charList = new ArrayList<String>();
		charList.add(GBK);
		charList.add(UTF_8);
		charList.add(UTF_16);
		charList.add(UTF_32);
		charList.add(ISO);
		charList.add(GB);

		HashSet<String> set = new HashSet<String>();
		for (String s1 : charList)
			for (String s2 : charList)
				set.add(s1 + "-->" + s2);
		Scanner scan = new Scanner(System.in);
		System.err.println("Please input your messy code");
		String input = scan.nextLine();
		String b = input;
		int i = 0;
		String s1;
		String s2;
		for (String s : set) {
			s1 = s.split("-->")[0];
			s2 = s.split("-->")[1];
			System.err.println((i++) + ":\t" + s + "\t" + new String(b.getBytes(s1), s2));
		}

		separativeLine();
		System.err.println("A. GBK\tB. UTF-8\tC. ISO-8859-1\tD. GB2312");
		separativeLine();
		System.err.println("please choose your \"decoding\" charset(ABCD)");
		HashMap<String, String> charsetMap = new HashMap<String, String>();
		charsetMap.put("A", GBK);
		charsetMap.put("B", UTF_8);
		charsetMap.put("C", ISO);
		charsetMap.put("D", GB);
		String decodingCharset = charsetMap.get(scan.nextLine().toUpperCase());
		separativeLine();
		System.err.println("please choose your \"encoding\" charset(ABCD)");
		String encodingCharset = charsetMap.get(scan.nextLine().toUpperCase());
		System.err.println("decodingcharset:" + decodingCharset);
		System.err.println("encodingcharset:" + encodingCharset);

	}

	public static String toUtf8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					System.out.println(ex);
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0) {
						k += 256;
					}
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}

	@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
	private static void encodingAndDecodingTest() throws Exception {
//		String original = "bmi:1qaz2wsx_prod";
//		BASE64Encoder encoder = new sun.misc.BASE64Encoder();
//		String afterDigest = encoder.encode(original.getBytes());
//		System.err.println("method 1 encoding:\t" + afterDigest);
//
//		byte[] bytes2 = Base64.encodeBase64(original.getBytes());// import
//																	// org.apache.commons.codec.binary.Base64;
//		afterDigest = new String(bytes2);
//		System.err.println("method 2 encoding:\t" + afterDigest);
//
//		byte[] bytes3 = original.getBytes();
//		Class clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
//		Method mainMethod = clazz.getMethod("encode", byte[].class);
//		mainMethod.setAccessible(true);
//		Object obj = mainMethod.invoke(null, bytes3);
//		afterDigest = (String) obj;
//		System.err.println("method 3 encoding:\t" + afterDigest);
//
//		System.err.println("****************");
//		BASE64Decoder decoder = new BASE64Decoder();
//		byte[] bytes = decoder.decodeBuffer(afterDigest);
//		String orignal = new String(bytes);
//		System.err.println("method 1 decoding:\t" + orignal);
//		System.err.print("method 2 decoding:\t");
//		for (byte ch : bytes)
//			System.err.print((char) ch);
//		System.err.println();
//
//		Class clazz3 = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
//		Method mainMethod3 = clazz3.getMethod("decode", String.class);
//		mainMethod3.setAccessible(true);
//		Object obj3 = mainMethod3.invoke(null, afterDigest);
//		byte[] byte3 = (byte[]) obj3;
//		orignal = new String(byte3);
//		System.err.print("method 3 decoding:\t" + orignal);

	}

	@SuppressWarnings({ "unused", "static-access" })
	private static void gbkAndUtf_8() throws Exception {
		String c = new URLDecoder().decode("%E5%BA%84%E7%9D%BF", "utf-8");
		String d = new URLDecoder().decode("%E7%BF%80", "utf-8");
		System.err.println(c);
		System.err.println(d);
	}

	private static void separativeLine() throws Exception {
		Thread.sleep(1000);
		System.err.println("***************************");
	}
}
